@IsTest
public with sharing class John_Test_Record_Merge {
    
    @IsTest
    static void mergeByDML(){
        Account acc1 = new Account(Name = '张三');
        Account acc2 = new Account(Name = '李四', Phone = '13688886666');
        insert acc1;
        insert acc2;

        Contact con = new Contact(FirstName = '三', LastName = '张');
        con.AccountId = acc2.Id;
        insert con;

        Test.startTest();
        merge acc1 acc2;
        Account masterAcc = [SELECT Id, Name, Phone, (SELECT FirstName,LastName FROM Contacts) FROM Account WHERE Name = '张三' limit 1];
        List<Account> slaverResult = [SELECT Id, Name FROM Account WHERE Id = :acc2.Id];  // 奴隶的下场

        System.assertEquals('三', masterAcc.getSObjects('Contacts')[0].get('FirstName'));  // 关联关系转移到主记录上了
        System.assertEquals(0, slaverResult.size());    // 从记录被merge后会被删除掉
        System.assertNotEquals('13688886666', masterAcc.Phone);  // 普通属性是不会merge到主记录上的

        List<Account> acc2Deleted = [SELECT Id,Name FROM Account WHERE Name = '李四' ALL ROWS];
        System.assertEquals(1, acc2Deleted.size());  // acc2被merge完处于deleted状态
        undelete acc2Deleted[0];  // 恢复被merge删除的记录
        List<Account> slaverResult2 = [SELECT Id, Name FROM Account WHERE Id = :acc2.Id];  // 奴隶的下场（又复活了）
        System.assertEquals(1, slaverResult2.size());
        System.assertEquals('三', masterAcc.getSObjects('Contacts')[0].get('FirstName'));  //  但是Contact关联的还是acc1
        Test.stopTest();
        
    }

    @IsTest
    static void mergeByDatabaseMethod(){
        Account acc1 = new Account(Name = '张三');
        Account acc2 = new Account(Name = '李四', Phone = '13688886666');
        insert acc1;
        insert acc2;

        Contact con = new Contact(FirstName = '三', LastName = '张');
        con.AccountId = acc2.Id;
        insert con;
        
        Test.startTest();
        //Database.MergeResult mergeResult = Database.merge(acc1, acc2, false);  // Merge一条记录
        List<Database.MergeResult> mergeResults = Database.merge(acc1, new List<Account>{acc2}, false);  // Merge两条记录
        Account masterAcc = [SELECT Id, Name, Phone, (SELECT FirstName,LastName FROM Contacts) FROM Account WHERE Name = '张三' limit 1];
        List<Account> slaverResult = [SELECT Id, Name FROM Account WHERE Id = :acc2.Id];  // 奴隶的下场
        Test.stopTest();

        for(Database.MergeResult res : mergeResults) {  // MergeResult对象操作
            System.assert(res.isSuccess());   // 获取Merge是否成功
            System.assertEquals(acc1.Id, res.getId());  // MergeResult中的getId就是master的Id
            List<Id> mergedIds = res.getMergedRecordIds();  // 获取被Merge对象的Id
            System.assertEquals(acc2.Id, mergedIds.get(0));
            List<Id> relatedIds = res.getUpdatedRelatedIds();  // 获取被更新引用关系的子对象Id(所有引用了被Merge对象的对象)
            System.assertEquals(con.Id, relatedIds.get(0));
        }
        
        System.assertEquals('三', masterAcc.getSObjects('Contacts')[0].get('FirstName'));  // 关联关系转移到主记录上了
        System.assertEquals(0, slaverResult.size());    // 从记录被merge后会被删除掉
        System.assertNotEquals('13688886666', masterAcc.Phone);  // 普通属性是不会merge到主记录上的
    }

}